home *** CD-ROM | disk | FTP | other *** search
/ PCMania 64 / PCMania CD64_1.iso / phy / phy005 / 3d / 3dv14.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-09-14  |  14.9 KB  |  487 lines

  1. {$M 65520,0,655200}                                                                               {
  2.  
  3. Vulkanus demo......  "My computer, My hero, My God, My life"
  4.  
  5. PROJECTE: EUSKAL PARTY : " TUNGUSKA " By Skynet                                }
  6.  
  7. Program TUNGUSKA;
  8.  
  9. Uses Crt,Grflib,PasDVT;   {Carregue la graph i el Vangelis Tracker}
  10.  
  11. Const Tecta=0.017453292519943295769;  {Operacions predisenyades}
  12.       COST =0.999847695156391239157;
  13.       SINT =0.017452406437283512819;
  14.  
  15.       arxiu='data2.asc';
  16.  
  17.       MAXVERTEX=750;
  18.       MAXFACES=1024;
  19.  
  20.  
  21. Type Enter=-1000..1000;
  22.      TresD=Record
  23.              X,Y,Z :Real;
  24.            End;
  25.      Graf =Record
  26.              A,B,C,Col:Enter;
  27.              D:TresD;
  28.            End;
  29.      Cent =Record
  30.              A:Enter;
  31.              B:Real;
  32.            End;
  33.      Palette=Record
  34.              R,G,B:Byte;
  35.            End;
  36.  
  37. Var Cad:String;
  38.     code,i,pol:Integer;
  39.     VArray:Array [0..MAXVERTEX] of TresD;
  40.     VPolig:Array [0..MAXFACES] of Graf;
  41.     PV,p:Byte;
  42.     Error:Boolean;
  43.     Vorto:Array[0..MAXFACES] of Cent;
  44.     f:file of palette;
  45.     paleta:palette;
  46.  
  47. { Procediments de Rotacio 3D--------------------------------------------- }
  48. {Realitzen una variacio de tots els components en cert sentit, A mes tambe
  49. realitzen la operacio sobre el ortocentre del poligon}
  50.  
  51.  
  52. {MOMENTANI....Cal realitzar una traça precalculada.......!!!!!!!!!!!}
  53.  
  54. Procedure Rotx(var Dades:Array of TresD;var Pol:Array of Graf);
  55.    Var i : integer;
  56.    Begin
  57.      for i := 0 to MAXVERTEX do
  58.        begin
  59.          dades[i].y := dades[i].y * COST + dades[i].z * SINT;
  60.          dades[i].z :=-dades[i].y * SINT + dades[i].z * COST;
  61.          If i<=MAXFACES then
  62.            begin
  63.              pol[i].D.y := pol[i].D.y * COST + pol[i].D.z * SINT;
  64.              pol[i].D.z :=-pol[i].D.y * SINT + pol[i].D.z * COST;
  65.            end;
  66.        end;
  67.    End;
  68.  
  69. Procedure Roty(var dades:Array of TresD;var Pol:Array of Graf);
  70.    Var i : integer;
  71.    Begin
  72.      For i := 0 to MAXVERTEX do
  73.        Begin
  74.          dades[i].x := dades[i].x * COST - dades[i].z * SINT;
  75.          dades[i].z := dades[i].x * SINT + dades[i].z * COST;
  76.          if i<=MAXFACES then
  77.             begin
  78.               pol[i].D.x:=pol[i].D.x*COST - pol[i].D.z* SINT;
  79.               pol[i].D.z:=pol[i].D.x*SINT + pol[i].D.z* COST;
  80.             end;
  81.        End;
  82.    End;
  83.  
  84. Procedure Rotz(var dades:Array of TresD;var Pol:Array of Graf);
  85.    Var i : integer;
  86.    Begin
  87.       For i := 0 to MAXVERTEX do
  88.         Begin
  89.            dades[i].x := dades[i].x * COST + dades[i].y * SINT;
  90.            dades[i].y :=-dades[i].x * SINT + dades[i].y * COST;
  91.            If i<=MAXFACES then
  92.              begin
  93.                pol[i].D.x:= pol[i].D.x*COST + pol[i].D.y*SINT;
  94.                pol[i].D.y:= pol[i].D.x*SINT + pol[i].D.y*COST;
  95.              End;
  96.         End;
  97.    End;
  98.  
  99. {Procediments de carrega dels poligons i dels vertex------------------------}
  100.  
  101. Function existeix(s:string):boolean;
  102.    Var f:file;
  103.    Begin
  104.      {$I-}
  105.      assign(f,s);
  106.      reset(f);
  107.      close(f);
  108.      {$I+}
  109.      existeix:=(IOResult=0) and (s <>'');
  110.    End;
  111.  
  112. Procedure Load_Vertex(Var VArray:Array of TresD;Var Error:Boolean);
  113.    Var I,n,j:Integer;
  114.        data:Text;
  115.        Cad,nombre:String;
  116.        car:char;
  117.     Begin
  118.        j:=0;
  119.        nombre:='';
  120.        assign(data,Arxiu);
  121.        if Not(existeix(arxiu)) then
  122.            Error:=True  {Activara el missatge d'error}
  123.        Else
  124.          Begin
  125.            Error:=False;
  126.            reset(data);
  127.            readln(data,cad);
  128.            delete(cad,14,100);
  129.            if not(cad='Ambient light') then
  130.               Error:=True
  131.            Else
  132.              Begin
  133.                While cad<>'Vertex list:' do
  134.                  readln(data,cad);
  135.                readln(data,cad);
  136.                While cad<>'Face list:' do
  137.                  begin
  138.                    cad:=cad+'                                                                    ';
  139.                    {El espai final parara la busqueda}
  140.                    n:=1;
  141.                    For I:=13 to 70 do
  142.                      if cad[i]=':' then
  143.                         begin
  144.                           if n=1 then {posar en X}
  145.                             begin
  146.                              Inc(n,1);
  147.                              while cad[i+2]<>' ' do
  148.                                Begin
  149.                                  nombre:=nombre+cad[i+2];
  150.                                  Inc(i,1);
  151.                                end;
  152.                              val(nombre,Varray[j].X,code); {La j es el vertex}
  153.                              Varray[j].X:=Varray[j].X+0.000666;
  154.                              nombre:='';
  155.                             end
  156.                           else
  157.                             if n=2 then {posar en Y}
  158.                               begin
  159.                                 Inc(n,1);
  160.                                 while cad[i+2]<>' ' do
  161.                                   Begin
  162.                                     nombre:=nombre+cad[i+2];
  163.                                     Inc(i,1);
  164.                                   end;
  165.                                 val(nombre,Varray[j].Y,code);
  166.                                 Varray[j].Y:=Varray[j].Y+0.000666;
  167.                                 nombre:='';
  168.                               end
  169.                             else        {posar en Z}
  170.                               begin
  171.                                 n:=0;
  172.                                 while cad[i+2]<>' ' do
  173.                                   Begin
  174.                                     nombre:=nombre+cad[i+2];
  175.                                     Inc(i,1);
  176.                                   end;
  177.                                 val(nombre,Varray[j].Z,code);
  178.                                 Varray[j].Z:=Varray[j].Z+0.000666;
  179.                                 nombre:='';
  180.                                 inc(j,1);
  181.                                 i:=70;
  182.                               end;
  183.                         end;
  184.                      readln(data,cad);
  185.                  end;
  186.              End;
  187.          End;
  188.        close(data);
  189.     End;
  190.  
  191. Procedure Load_Poligon(Var Vpolig:Array of Graf;var j:integer);
  192.    Var I,n:Integer;
  193.        Cad,comp,nombre:String;
  194.        data:text;
  195.     Begin
  196.       j:=0;
  197.       nombre:='';
  198.       Assign(data,arxiu);
  199.       reset(data);
  200.       readln(data,cad);
  201.       While cad<>'Face list:' do
  202.         readln(data,cad);
  203.       readln(data,cad);
  204.       While not(eof(data)) do
  205.         Begin
  206.             comp:=cad;
  207.             delete(comp,5,100);
  208.             if not(comp='Face') then
  209.                readln(data,cad)
  210.             else
  211.               begin
  212.                 cad:=cad+'                                                                    ';
  213.                    {El espai final parara la busqueda}
  214.                    n:=1;
  215.                    For I:=10 to 50 do
  216.                      if cad[i]=':' then
  217.                         begin
  218.                           if n=1 then {posar en X}
  219.                             begin
  220.                              Inc(n,1);
  221.                              while cad[i+1]<>' ' do
  222.                                Begin
  223.                                  nombre:=nombre+cad[i+1];
  224.                                  Inc(i,1);
  225.                                end;
  226.                              val(nombre,Vpolig[j].a,code); {La j es el vertex}
  227.                              nombre:='';
  228.                             end
  229.                           else
  230.                             if n=2 then {posar en Y}
  231.                               begin
  232.                                 Inc(n,1);
  233.                                 while cad[i+1]<>' ' do
  234.                                   Begin
  235.                                     nombre:=nombre+cad[i+1];
  236.                                     Inc(i,1);
  237.                                   end;
  238.                                 val(nombre,Vpolig[j].b,code);
  239.                                 nombre:='';
  240.                               end
  241.                             else        {posar en Z}
  242.                               begin
  243.                                 n:=0;
  244.                                 while cad[i+1]<>' ' do
  245.                                   Begin
  246.                                     nombre:=nombre+cad[i+1];
  247.                                     Inc(i,1);
  248.                                   end;
  249.                                 val(nombre,Vpolig[j].c,code);
  250.                                 nombre:='';
  251.                                 inc(j,1);
  252.                                 i:=50;
  253.                               end;
  254.                         end;
  255.                      readln(data,cad);
  256.                 End;
  257.         End;
  258.     End;
  259.  
  260. Procedure Create_Ortocenters(Varray:Array of TresD;var Vpolig:Array of Graf;pol:integer;var Vorto:Array of cent);
  261.   Var I:Integer;
  262.    Begin
  263.      For I:=0 to POL-1 do
  264.        Begin
  265.          Vpolig[I].D.X:=(Varray[Vpolig[I].a].x+Varray[Vpolig[I].b].x+Varray[Vpolig[I].c].x)/3;
  266.          Vpolig[I].D.Y:=(Varray[Vpolig[I].a].y+Varray[Vpolig[I].b].y+Varray[Vpolig[I].c].y)/3;
  267.          Vpolig[I].D.Z:=(Varray[Vpolig[I].a].z+Varray[Vpolig[I].b].z+Varray[Vpolig[I].c].z)/3;
  268.          Vorto[I].a:=i;
  269.          Vorto[I].b:=Vpolig[I].D.Z;
  270.          Vpolig[I].col:=i;
  271.        End;
  272.    End;
  273.  
  274. Procedure Orto_Sort(Vpolig:Array of Graf;pol:integer;VAR VOrtos:Array of Cent);
  275.   Var I,J:Integer;
  276.      procedure quicksort(var a:Array of cent; Lo,Hi: integer);
  277.          procedure sort(l,r: integer);
  278.              var x,y: real;
  279.                  i,j,temp,temp2:integer;
  280.                begin
  281.                  i:=l; j:=r; x:=a[(l+r) DIV 2].b;
  282.                  repeat
  283.                    while a[i].b<x do i:=i+1;
  284.                      while x<a[j].b do j:=j-1;
  285.                        if i<=j then
  286.                          begin
  287.                            temp:=a[i].a;a[i].a:=a[j].a;a[j].a:=temp;
  288.                            y:=a[i].b; a[i].b:=a[j].b; a[j].b:=y;
  289.                            i:=i+1; j:=j-1;
  290.                          end;
  291.                  until i>j;
  292.                  if l<j then sort(l,j);
  293.                  if i<r then sort(i,r);
  294.                end;
  295.  
  296.          begin {quicksort};
  297.            sort(Lo,Hi);
  298.          end;
  299.     Begin
  300.       Quicksort(VOrtos,0,pol);
  301.     End;
  302.  
  303.  
  304. { Dibuixa tots els poligons que conte el objecte ----------------------------}
  305.  
  306. Procedure Poligono (x1,y1,x2,y2,x3,y3,col:integer;pv:byte;origex,origey:integer);
  307.  Var  inc_ent,inc_par,pos_ent,pos_par:longint;
  308.       temp,cont,cont2,xmin,xmax      :integer;
  309.  
  310. Begin
  311.  
  312.  x1:=x1+origex;
  313.  x2:=x2+origex;
  314.  x3:=x3+origex;
  315.  y1:=y1+origey;
  316.  y2:=y2+origey;
  317.  y3:=y3+origey;
  318.      if Y1>Y3 then
  319.         begin
  320.              temp:=X3;
  321.              X3:=X1;
  322.              X1:=temp;
  323.              temp:=Y3;
  324.              Y3:=Y1;
  325.              Y1:=temp;
  326.         end;
  327.  
  328.      if Y1>Y2 then
  329.         begin
  330.              temp:=X2;
  331.              X2:=X1;
  332.              X1:=temp;
  333.              temp:=Y2;
  334.              Y2:=Y1;
  335.              Y1:=temp;
  336.         end;
  337.  
  338.      if Y2>Y3 then
  339.         begin
  340.              temp:=X3;
  341.              X3:=X2;
  342.              X2:=temp;
  343.              temp:=Y3;
  344.              Y3:=Y2;
  345.              Y2:=temp;
  346.         end;
  347.     pos_ent:=65536*X1;
  348.     if (Y3-Y1)>0 then inc_ent:=65536*(X3-X1) div (Y3-Y1);
  349.     pos_par:=65536*X1;
  350.     if (Y2-Y1)>0 then inc_par:=65536*(X2-X1) div (Y2-Y1);
  351.     for cont:=Y1 to Y2-1 do
  352.         begin
  353.              xmin:=pos_ent div 65536;
  354.              xmax:=pos_par div 65536;
  355.              if xmax<xmin then
  356.                 begin
  357.                      temp:=xmax;
  358.                      xmax:=xmin;
  359.                      xmin:=temp;
  360.                 end;
  361.              for cont2:=xmin to xmax-1 do fponpixel(cont2,cont,col,pv);
  362.              pos_ent:=pos_ent+inc_ent;
  363.              pos_par:=pos_par+inc_par;
  364.         end;
  365.     pos_par:=65536*X2;
  366.     if (Y3-Y2)>0 then inc_par:=65536*(X3-X2) div (Y3-Y2);
  367.     for cont:=Y2 to Y3-1 do
  368.         begin
  369.              xmin:=pos_ent div 65536;
  370.              xmax:=pos_par div 65536;
  371.              if xmax<xmin then
  372.                 begin
  373.                      temp:=xmax;
  374.                      xmax:=xmin;
  375.                      xmin:=temp;
  376.                 end;
  377.              for cont2:=xmin to xmax-1 do ponpixel(cont2,cont,col,pv);
  378.              pos_ent:=pos_ent+inc_ent;
  379.              pos_par:=pos_par+inc_par;
  380.         end;
  381. end;
  382.  
  383. Procedure Draw_3d(Varray:Array of TresD;Vpolig:Array of graf;
  384.                         c,pv:byte;origeX,origeY,pol:Integer;vorto:array of cent);
  385.  
  386.  
  387.    Procedure lines(x1, y1, x2, y2: real;c,pv:byte;origeX,OrigeY:integer);
  388.    Begin
  389.     fLinea(round(x1) + origeX,round(y1) + origeY,round(x2) + origeX,round(y2) + origeY,c,PV);
  390.    End;
  391.  
  392.    Var I:integer;
  393.  
  394.       Begin
  395.         For I:=0 to (pol-1) do
  396.           Begin
  397.            poligono(round(Varray[Vpolig[Vorto[I].a].a].X),round(Varray[Vpolig[vorto[I].a].a].y),
  398.            round(Varray[Vpolig[vorto[i].a].b].X),round(Varray[Vpolig[vorto[i].a].b].y),
  399.            round(Varray[Vpolig[vorto[i].a].c].X),round(Varray[Vpolig[vorto[i].a].c].y),Vpolig[i].col,pv,origex,origey);
  400.  
  401.           End
  402.       End;
  403.  
  404. Procedure Increment(Var Varray:Array of TresD;n:real);
  405.    Var I:integer;
  406.    Begin
  407.      For I:=0 to 660 do
  408.        Begin
  409.         Varray[i].x:=(Varray[i].x/100)*n;
  410.         Varray[i].y:=(Varray[i].y/100)*n;
  411.         Varray[i].z:=(Varray[i].z/100)*n;
  412.        End;
  413.    End;
  414.  
  415. {-------------------------------Programa Principal---------------------------}
  416.  
  417.  
  418. BEGIN
  419.  {OUTPUT-----------------------------------}
  420.  
  421.   ClrScr;
  422.   TextBackground(Blue);
  423.   Writeln('3D Vulkanus.                    PROJECTE TUNGUSKA.                  By Skynet');
  424.   TextBackground(Black);
  425.   Writeln;
  426.   Writeln;
  427.  
  428.  {-----------------Programa----------------}
  429.  
  430. {  IF NOT VT_Init THEN
  431.     BEGIN
  432.      WriteLn('Driver no detectat! Si continues, no obtindras musica...');
  433.      readln;
  434.     END;
  435.  
  436.   {ENTORN DEL VANGELIS TRACKER-------Llegir intruccions}
  437.  
  438. {  VT_GoTo(1, 1);
  439.   VT_Autoon;
  440.   VT_SetVolume(255);
  441.   VT_Start;
  442.   VT_SyncStart;
  443.  
  444.   {ALGORITMES ARXIUS------------------------------------}
  445.  
  446.   Load_Vertex (VArray,Error);
  447.   If Error then
  448.      Begin
  449.        Writeln('Arxiu no trobat o aquest no correspon al format del 3D Studio');
  450.        readln;
  451.        halt(27);
  452.      End;
  453.   Load_Poligon(VPolig,pol);
  454.   Create_Ortocenters(Varray,Vpolig,pol,Vorto);
  455.   {ALGORITMES GRAFICS-----------------------------------}
  456.  
  457.   ModoGrafico;
  458.   PV:=CreaVirtual;
  459.   fBorraPantalla(0,0);
  460.   fBorraPantalla(0,PV);
  461.   increment(varray,70);
  462.    for i:=0 to 255 do
  463.      poncolor(i,0,0,i);
  464.   repeat
  465.     draw_3d(VArray,Vpolig,0,pv,160,100,pol,vorto);
  466.     CopiaPantalla(PV,0);
  467.     rotx(Varray,Vpolig);
  468.     roty(Varray,Vpolig);
  469.     rotz(Varray,Vpolig);
  470.     fborrapantalla(0,pv);
  471.     Orto_Sort(Vpolig,pol,VOrto);
  472.   until keypressed;
  473.  
  474.   Fadedown(2000,1,0);
  475.  
  476.  { For p:=VT_GetVolume downto 0 do
  477.     Begin
  478.      VT_Setvolume(p);
  479.      delay(3);
  480.     End;}
  481.  
  482.   ModoTexto;
  483.  { VT_AutoOff;
  484.   VT_Abort;}
  485.  
  486. END.
  487.